package com.starleague.entity.android;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.starleague.entity.IEntity;
import com.starleague.entity.IEntityVisitor;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

public class SimpleEntityView
        extends AbstractEntityView
{
    final Map<String, TextView> nameValueViewMap = new HashMap<>();
    private final IEntityVisitor updateVisitor = new UpdateVisitor();

    public SimpleEntityView(Context context,
                            AttributeSet attrs)
    {
        super(context, attrs);
    }

    public SimpleEntityView(Context context,
                            AttributeSet attrs,
                            int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    public void setEntity(IEntity entity)
    {
        super.setEntity(entity);
        entity.accept(new BindVisitor());
    }

    @Override
    protected void doUpdate()
    {
        this.getEntity().accept(this.updateVisitor);
    }

    // @Override
    // protected void onAttachedToWindow()
    // {
    // super.onAttachedToWindow();
    //
    // this.entity.accept(new BindVisitor());
    // this.entity.accept(this.updateVisitor);
    //
    // if (this.entity instanceof IObservable)
    // ((IObservable) this.entity).addObserver(this);
    // }
    //
    @Override
    protected void onDetachedFromWindow()
    {
        this.nameValueViewMap.clear();

        super.onDetachedFromWindow();
    }

    class BindVisitor
            implements IEntityVisitor
    {
        @Override
        public void visit(String name,
                          Object value)
        {
            View subView = SimpleEntityView.this.findViewWithTag(name);
            if (subView != null)
            {
                if (value instanceof IEntity)
                {
                    IEntity subEntity = (IEntity) value;
                    AbstractEntityView subEntityView = (AbstractEntityView) subView;
                    subEntityView.setEntity(subEntity);
                }
                else if (value instanceof Collection)
                {
                    // Collection<?> collection = (Collection<?>) value;
                    // for (Object subValue:collection)
                    // {
                    //
                    // }
                    // append(index, name, collection.getClass().getSimpleName()
                    // +
                    // " ["
                    // + collection.size() + "] ");
                    // if (this.currentDepth >= 0)
                    // {
                    // int subIndex = 0;
                    // for (Object item : collection)
                    // {
                    // visit(subIndex++, null, item);
                    // }
                    // }
                }
                else
                {
                    SimpleEntityView.this.nameValueViewMap.put(name, (TextView) subView);
                }
            }
        }
    }

    class UpdateVisitor
            implements IEntityVisitor
    {
        @Override
        public void visit(String name,
                          Object value)
        {
            if (value instanceof IEntity)
            {
                // IEntity entity = (IEntity) value;
                // EntityView entityView = (EntityView) subView;
                // entityView.setEntity(entity);
            }
            else if (value instanceof Collection)
            {
                // Collection<?> collection = (Collection<?>) value;
                // for (Object subValue:collection)
                // {
                //
                // }
                // append(index, name, collection.getClass().getSimpleName()
                // +
                // " ["
                // + collection.size() + "] ");
                // if (this.currentDepth >= 0)
                // {
                // int subIndex = 0;
                // for (Object item : collection)
                // {
                // visit(subIndex++, null, item);
                // }
                // }
            }
            else
            {
                TextView textView = SimpleEntityView.this.nameValueViewMap.get(name);
                if (textView != null)
                    textView.setText(value.toString());
            }
        }
    }

    protected void init(Context context,
                        AttributeSet attrs)
    {
        //
    }
}

// private static class EntityBindingVisitor
// implements IEntityVisitor
// { entity.accept(new EntityBindingVisitor(itemView));
//
// private Deque<View> viewStack = new ArrayDeque<>();
//
// EntityBindingVisitor(View itemView)
// {
// this.viewStack.push(itemView);
// }
//
// private View currentView()
// {
// return this.viewStack.peek();
// }
//
// @Override
// public void visit(String name,
// Object value)
// {
// if (value instanceof IEntity)
// {
// IEntity entity = (IEntity) value;
// EntityView entityView = (EntityView)currentView().findViewWithTag(name);
// entityView
// append(index, name, entity.getEntityName());
// if (this.currentDepth >= 0)
// {
// entity.accept(this);
// }
// }
// else if (value instanceof Collection)
// {
// Collection<?> collection = (Collection<?>) value;
// append(index, name, collection.getClass().getSimpleName() + " [" +
// collection.size() + "] ");
// if (this.currentDepth >= 0)
// {
// int subIndex = 0;
// for (Object item : collection)
// {
// visit(subIndex++, null, item);
// }
// }
// }
// else
// {
// append(index, name, value);
// }
// // for (ITrait trait : hasTraits.getTraits())
// // {
// // AbstractTraitView traitView = (AbstractTraitView)
// // view.findViewWithTag(trait.getName());
// // if (traitView != null)
// // traitView.setTrait(trait);
// // }
// // for (ITrait trait : hasTraits.getTraits())
// // {
// // AbstractTraitView traitView = (AbstractTraitView)
// // itemView.findViewWithTag(trait.getName());
// // if (traitView != null)
// // traitView.setTrait(trait);
// // }
// }
// }
// protected ITrait getTrait()
// {
// return this.trait;
// }
//
// public void setTrait(ITrait trait)
// {
// this.trait = trait;
//
// if (this.nameView != null)
// this.nameView.setText(this.trait.getName());
//
// if (this.labelView != null)
// this.labelView.setText(this.trait.getLabel());
//
// onTraitChanged();
//
// if (trait instanceof IObservable)
// ((IObservable) trait).addObserver(this);
// }
//
// @Override
// protected void onFinishInflate()
// {
// super.onFinishInflate();
// this.nameView = (TextView) this.findViewWithTag(TAG_NAME);
// this.labelView = (TextView) this.findViewWithTag(TAG_LABEL);
// }
//
// @Override
// public void update(Observable observable,
// Object data)
// {
// this.post(new Runnable()
// {
// @Override
// public void run()
// {
// onTraitChanged();
// }
// });
// }
//
// protected abstract void onTraitChanged();